package org.simple.framework.data.query;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;

/**
 * 项目名称：simple-framework
 * 类名称：ExpressionHandler
 * 类描述：ExpressionHandler
 * 创建时间：2018/9/10
 *
 * @author sisyphus   (E-mail:1620657419@qq.com)
 * @version v1.0
 */
public abstract class ExpressionHandler<T> {

    public T handle(Expression exp, Match match) {
        switch (exp) {
            case EQ:
                return handleEq();
            case NEQ:
                return handleNeq();
            case LIKE:
                return handleLike(match);
            case NOT_LIKE:
                return handleNotLike(match);
            case IN:
                return handleIn();
            case NOT_IN:
                return handleNotIn();
            case GT:
                return handleGt();
            case LT:
                return handleLt();
            case GTE:
                return handleGte();
            case LTE:
                return handleLte();
            case IS_NULL:
                return handleIsNull();
            case IS_NOT_NULL:
                return handleIsNotNull();
            case REGEX:
                return handleRegex(match);
            default:
                throw new UnsupportedOperationException("Unsupported Operation:" + exp);
        }
    }

    protected <U> List<U> handleIterableValue(U value) {
        List<U> results = new ArrayList<>();
        if (value.getClass().isArray()) {
            results.addAll(Arrays.asList(((U[]) value)));
        } else if (Collection.class.isInstance(value)) {
            results.addAll((Collection<U>) value);
        } else {
            results.add(value);
        }
        return results;
    }

    protected boolean isExpressionSupportIterableValue(Expression expression) {
        return Expression.IN.equals(expression) || Expression.NOT_IN.equals(expression);
    }

    protected abstract T handleEq();

    protected abstract T handleNeq();

    protected abstract T handleLike(Match match);

    protected abstract T handleNotLike(Match match);

    protected abstract T handleIn();

    protected abstract T handleNotIn();

    protected abstract T handleGt();

    protected abstract T handleLt();

    protected abstract T handleGte();

    protected abstract T handleLte();

    protected abstract T handleIsNull();

    protected abstract T handleIsNotNull();

    protected abstract T handleRegex(Match match);

}
